﻿using System;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace Games.Common
{
    public static class ViewExtensions
    {
        public static Task<bool> ColorTo(this VisualElement self, Color fromColor, Color toColor, Action<Color> callback, uint length = 250, Easing easing = null)
        {
            Func<double, Color> transform = (t) => Color.FromRgba(fromColor.R + t * (toColor.R - fromColor.R),
                             fromColor.G + t * (toColor.G - fromColor.G),
                             fromColor.B + t * (toColor.B - fromColor.B),
                             fromColor.A + t * (toColor.A - fromColor.A));
            return ColorAnimation(self, "ColorTo", transform, callback, length, easing);
        }

        public static void CancelColorTo(this VisualElement self)
        {
            self.AbortAnimation("ColorTo");
        }

        static Task<bool> ColorAnimation(VisualElement element, string name, Func<double, Color> transform, Action<Color> callback, uint length, Easing easing)
        {
            easing = easing ?? Easing.Linear;
            var taskCompletionSource = new TaskCompletionSource<bool>();

            element.Animate<Color>(name, transform, callback, 16, length, easing, (v, c) => taskCompletionSource.SetResult(c));
            return taskCompletionSource.Task;
        }

        public static async Task ScaleBack(this VisualElement element, double rate, uint length = 200)
        {
            await element.ScaleTo(rate, length / 2, Easing.CubicIn);
            await element.ScaleTo(1, length / 2, Easing.CubicOut);
        }

        public static void Show(this VisualElement element, double startOpacity = 0, double startSacle = 0, uint length = 500)
        {
            element.Opacity = startOpacity;
            element.Scale = startSacle;
            element.ScaleTo(1, length, Easing.CubicOut);
            element.FadeTo(1, length, Easing.CubicOut);
        }

        public static void Hide(this VisualElement element, double endOpacity = 0, double endSacle = 0, uint length = 500)
        {
            element.ScaleTo(endSacle, length, Easing.CubicIn);
            element.FadeTo(endOpacity, length, Easing.CubicIn);
        }

        public static void ShowToastMessage(this View view, string message, bool fase = true)
        {
            DependencyService.Get<IToastHandler>().ShowToast(message, fase);
        }

        public static void ShowToastMessage(this ContentPage page, string message, bool fase = true)
        {
            DependencyService.Get<IToastHandler>().ShowToast(message, fase);
        }
    }
}